package com.zjcode.cdcer.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.export.template.ExcelExportOfTemplateUtil;
import com.alibaba.fastjson.JSONObject;
import com.chinatechstar.component.commons.consts.Consts;
import com.chinatechstar.component.commons.controller.BaseController;
import com.chinatechstar.component.commons.entity.MqData;
import com.chinatechstar.component.commons.enums.Nation;
import com.chinatechstar.component.commons.result.ListResult;
import com.chinatechstar.component.commons.result.ResultBuilder;
import com.chinatechstar.component.commons.supports.PageData;
import com.chinatechstar.component.commons.utils.ExcelUtils;
import com.chinatechstar.component.commons.utils.UuidUtil;
import com.zjcode.cdcer.config.MConsts;
import com.zjcode.cdcer.mapper.ZjcodeSysRegionMapper;
import com.zjcode.cdcer.model.*;
import com.zjcode.cdcer.model.basic.JsonObj;
import com.zjcode.cdcer.service.CerPersonInfoService;
import com.zjcode.cdcer.service.SysUserService;
import com.zjcode.cdcer.service.TkmSysOrgService;
import com.zjcode.cdcer.service.TkmSysUserService;
import com.zjcode.cdcer.service.impl.SequenceService;
import com.zjcode.cdcer.utils.ExcelUtil;
import com.zjcode.cdcer.utils.Utils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.map.HashedMap;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @createTime: 2023-09-27
 * @creater: yong
 * 基础人员信息
 */
@RestController
@Slf4j
@RequestMapping("/v1/cerpersoninfo/")
public class CerPersonInfoController extends BaseController {
    @Autowired
    private CerPersonInfoService personInfoService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private TkmSysUserService tkmSysUserService;
    @Autowired
    private TkmSysOrgService tkmSysOrgService;

    @Autowired
    private SequenceService sequenceService;

    @Value("${studio.cer-personinfo-file-in-disk}")
    private String cerPersonFileInDisk;

    @GetMapping("nationlist")
    @ApiOperation("民族列表")
    public ListResult<Object> listPageData() {
        List<String> nationlist = Arrays.stream(Nation.values()).map(e->e.description).collect(Collectors.toList());
        return ResultBuilder.buildListSuccess(nationlist);
    }
    @PostMapping("listPagePerson")
    @ApiOperation("基础人员信息列表查询")
    public ListResult<Object> listPagePerson() {
        PageData pageData=this.getPageData();
        return ResultBuilder.buildListSuccess(personInfoService.listPageData(pageData));
    }
    @GetMapping("getPersonInfo")
    @ApiOperation("基础人员信息主键查询")
    public JsonObj getPersonInfo(@RequestParam String id) {
        CerPersonalInfo personInfoById = personInfoService.getPersonInfoById(id);
        HashMap<String, Object> res = new HashMap<>();
        res.put("person",personInfoById);
        return JsonObj.success(res);
    }
    @PostMapping("addPersonInfo")
    @ApiOperation("基础人员信息添加")
    public JsonObj addPersonInfo() {
        PageData pageData = getPageData();
        String userId = (String) pageData.get("userId");
        String json = JSONObject.toJSONString(pageData);
        CerPersonalInfo info = JSONObject.parseObject(json, CerPersonalInfo.class);
        // 获取extFlag
        String extFlag = sysUserService.findUserExtFlag(userId);
        // 获取用户的省市县区机构的编码与名称
        TkmUserOrgAndRegions regionsAndOrg = tkmSysUserService.findUserRegionsAndOrg(userId);
        SysOrg userOrg = regionsAndOrg.getSysOrg();
        List<ZjcodeSysRegion> userRegions = regionsAndOrg.getRegions();
        String orgId = userOrg
                .getId()
                .toString();
        // 放入用户机构数据
        info.setExtFlag(extFlag);
        info.setInstitutionId(orgId);
        info.setCreateBy(userId);
        info.setInstitutionName(userOrg.getOrgName());
        if (StringUtils.isNotEmpty(info.getName())
                && StringUtils.isNotEmpty(info.getIdCard())
                && StringUtils.isNotEmpty(info.getProvinceName())
                && StringUtils.isNotEmpty(info.getDistrictName())
                && StringUtils.isNotEmpty(info.getCityName())
                && StringUtils.isNotEmpty(info.getCountyName())
                && StringUtils.isNotEmpty(info.getVillageName())
                && StringUtils.isNotEmpty(info.getSex())
                && StringUtils.isNotEmpty(info.getVillageId())
                && StringUtils.isNotEmpty(info.getNationCode())
                && StringUtils.isNotEmpty(info.getPhone())
                && StringUtils.isNotEmpty(info.getBirthday())){
            //判断该机构下是否有该人员
            int personCount=personInfoService.getCountByIdCardAndInstitutionId(orgId,info.getIdCard());
            if (personCount>0){
                return JsonObj.error("该机构下人员身份证信息重复！重复身份证为"+info.getIdCard());
            }

            String sequenceNumByCode = sequenceService.getSequenceByCode(info.getVillageId());
            info.setScreeningId(sequenceNumByCode);
            int i = personInfoService.insertCerPersonInfo(info);
            if (i>0)
            return JsonObj.success("添加成功");
            else
                return JsonObj.error("添加失败请检查添加信息");
        }
        return JsonObj.error("信息不全，请检查传参");

    }

    @PostMapping("editPersonInfo")
    @ApiOperation("基础人员信息更新")
    public JsonObj editPersonInfo() {
        PageData pageData=this.getPageData();
        String json = JSONObject.toJSONString(pageData);
        CerPersonalInfo info = JSONObject.parseObject(json, CerPersonalInfo.class);
        personInfoService.updateCerPersonInfo(info);
        return JsonObj.success("修改成功");
    }

    @PostMapping("queryPersonInfoByNameOrIdCard")
    @ApiOperation("数据上报-新增：根据姓名和身份证号(及选择的村code)查询基础信息")
    public ListResult<Object> queryPersonInfoByNameOrIdCard() {
        PageData pageData=this.getPageData();
        return ResultBuilder.buildListSuccess(personInfoService.listDataByNameOrIdCard(pageData));
    }

    @PostMapping("getVillagesByNameOrIdCard")
    @ApiOperation("数据上报-新增：根据姓名和身份证号查询绑定村集合")
    public JsonObj getVillagesByNameOrIdCard() {
        PageData pageData=this.getPageData();
        return personInfoService.getVillagesByNameOrIdCard(pageData);
    }


    @GetMapping("/getCity")
    @ApiOperation("获取地区数据根据层级")
    public ListResult<Object> getCity() {
        PageData pageData=this.getPageData();
        List<CityEntity> city = sequenceService.getCity(pageData.getString("level"), pageData.getString("parentCode"));
        ListResult<Object> objectListResult = ResultBuilder.buildListSuccess(city);
        objectListResult.setSuccess(true);
        return objectListResult;
    }

    @PostMapping(value = "/uploadFile4CerDataInit")
    @ApiOperation("基础人员信息上传")
    public JsonObj uploadFile4CerDataInit(@RequestParam("file") MultipartFile file,HttpServletResponse response)
            throws IOException {
        log.info("上传基础人员信息");

        PageData pageData = getPageData();
        String userId = (String) pageData.get("user");
        ImportParams params = new ImportParams();
        params.setTitleRows(1);
        File tmpfile = new File(generateCerDataInitFileSavePath(file,userId));
        FileUtils.copyInputStreamToFile(file.getInputStream(), tmpfile);
        // 解析excel
        List<CerPersonalData> list = ExcelImportUtil.importExcel(tmpfile,
                CerPersonalData.class,
                params);
        list = list
                .stream()
                .filter(each -> StringUtils.isNotEmpty(each.getName())).collect(Collectors.toList());
        // 数据过滤
/*        list = list
                .stream()
                .filter(each -> StringUtils.isNotEmpty(each.getName())
                        && StringUtils.isNotEmpty(each.getIdCard())
                        && StringUtils.isNotEmpty(each.getProvinceName())
                        && StringUtils.isNotEmpty(each.getDistrictName())
                        && StringUtils.isNotEmpty(each.getCityName())
                        && StringUtils.isNotEmpty(each.getCountyName())
                        && StringUtils.isNotEmpty(each.getVillageName())
                        && StringUtils.isNotEmpty(each.getSex())
                        && StringUtils.isNotEmpty(each.getNationCode())
                        && StringUtils.isNotEmpty(each.getPhone())
                        && StringUtils.isNotEmpty(each.getBirthday()))
                .collect(Collectors.toList());*/
        // 将TCerPersonalData转换成CerPersonalInfo
        List<CerPersonalInfo> importInfoList = list
                .stream()
                .map(each -> {
                    CerPersonalInfo target = getCerPersonalInfo(each);
                    return target;
                })
                .collect(Collectors.toList());
        // 获取extFlag
        String extFlag = sysUserService.findUserExtFlag(userId);
        // 获取用户的省市县区机构的编码与名称
        TkmUserOrgAndRegions regionsAndOrg = tkmSysUserService.findUserRegionsAndOrg(userId);
        SysOrg userOrg = regionsAndOrg.getSysOrg();
        List<ZjcodeSysRegion> userRegions = regionsAndOrg.getRegions();

        // 对需要导入的数据进行验证
        importInfoList
                .parallelStream()
                .forEach(each -> {
                    List<String> errors = Utils.validateCerPersonalInfoData(each);
                    if (errors.size() > 0) {
                        each.setIsHaveError(1);
                        each.setErrorMessage(errors
                                .stream()
                                .collect(Collectors.joining("|")));
                    } else {
                        each.setIsHaveError(0);
                        each.setErrorMessage("");
                    }
                });
        // 执行数据插入前的准备工作
        importInfoList
                .stream()
                .forEach(each -> {
                    each.setId(UuidUtil.get32UUID());
                    each.setCreateBy(userId);
                    each.setExtFlag(extFlag);
                    //民族
                    if (Nation.getDescriptionByCode(each.getNationCode())!=null){
                        each.setNationName(Nation.getDescriptionByCode(each.getNationCode()));
                    }else {
                        each.joinErrorMessage("民族序号范围1-56");
                    }
                    // 放入省市县区数据
                    //查询省级编号
                    CityEntity provincesInfoByName = sequenceService.getProvincesInfoByName(each.getProvinceName(), each.getProvinceName());
                    if (provincesInfoByName!=null){
                        each.setProvinceId(provincesInfoByName.getCode());
                        //查询市
                        CityEntity cityInfoByName = sequenceService.getCityInfoByName(each.getProvinceId(), each.getCityName());
                        if (cityInfoByName!=null){
                            each.setCityId(cityInfoByName.getCode());
                            //查询区
                            CityEntity AreaInfoByName = sequenceService.getAreaInfoByName(each.getCityId(), each.getDistrictName());
                            if (AreaInfoByName!=null){
                                each.setDistrictId(AreaInfoByName.getCode());
                                //查询乡镇
                                CityEntity StreetInfo = sequenceService.getStreetInfoByName(each.getDistrictId(), each.getCountyName());
                                if (StreetInfo!=null){
                                    each.setCountyId(StreetInfo.getCode());
                                    //查询村
                                    CityEntity VillageInfo = sequenceService.getVillageInfoByName(each.getCountyId(), each.getVillageName());
                                    if (VillageInfo!=null){
                                        each.setVillageId(VillageInfo.getCode());
                                    }else {
                                        each.joinErrorMessage("村级信息匹配异常");
                                    }
                                }else {
                                    each.joinErrorMessage("乡镇信息匹配异常");
                                }
                            }else {
                                each.joinErrorMessage("区信息匹配异常");
                            }
                        }else {
                            each.joinErrorMessage("市信息匹配异常");
                        }
                    }else {
                        each.joinErrorMessage("省信息匹配异常");
                    }
                   /* if (userRegions.size() > 0) {
                        userRegions
                                .parallelStream()
                                .forEach(region -> {
                                    String regionType = region.getRegionType();
                                    switch (regionType) {
                                        case "province":
                                            //判断省是否和添加人相同
                                            if (each.getProvinceName().equals(region.getRegionName())){
                                                each.setProvinceId(region.getRegionCode());
                                                each.setProvinceName(region.getRegionName());
                                            }
                                            else {
                                                each.joinErrorMessage("省份和创建人所在"+region.getRegionName()+"冲突");
                                            }
                                            break;
                                        case "city":
                                            if (each.getCityName().equals(region.getRegionName())){
                                                each.setCityId(region.getRegionCode());
                                                each.setCityName(region.getRegionName());
                                            }
                                            else {
                                                each.joinErrorMessage("城市和创建人所在"+region.getRegionName()+"冲突");
                                            }
                                            break;
                                        case "district":
                                            if (each.getDistrictName().equals(region.getRegionName())){
                                                each.setDistrictId(region.getRegionCode());
                                                each.setDistrictName(region.getRegionName());
                                            }
                                            else {
                                                each.joinErrorMessage("区县和创建人所在"+region.getRegionName()+"冲突");
                                            }
                                            break;
                                    }
                                });
                    }
                    personInfoService.checkStreetAndVillage(each);*/
                    String orgId = userOrg
                            .getId()
                            .toString();
                    // 放入用户机构数据
                    each.setInstitutionId(orgId);
                    each.setInstitutionName(userOrg.getOrgName());


                });
        importInfoList.forEach(each -> {
            log.info(each.toString());
        });
        // 执行数据写入
        //过滤出没有错误信息的添加，有错误信息的导出
        List<CerPersonalInfo> insertList = importInfoList.stream().filter(info ->
                info.getIsHaveError() == 0
        ).collect(Collectors.toList());
        if (insertList.size() > 0) {
            //设置系统唯一标识
            for (CerPersonalInfo cerPersonalInfo : insertList) {
                String sequenceNumByCode = sequenceService.getSequenceByCode(cerPersonalInfo.getVillageId());
                cerPersonalInfo.setScreeningId(sequenceNumByCode);
            }
            int count = personInfoService.insertRecords(insertList);
            log.info("农癌人员基础信息上报成功，共{}条数据", count);
        }
        //导出错误数据
        List<LinkedHashMap<String, Object>> dataList  = importInfoList.stream().filter(info ->
                info.getIsHaveError() == 1
        ).map( e->toLinkedHashMap(e)).collect(Collectors.toList());
        // 组装表头
        List<String> headList = Arrays.asList("省份",
                "城市",
                "所属区县",
                "所属乡镇",
                "所属村",
                "姓名",
                "性别",
                "民族",
                "身份证号码",
                "出生日期",
                "住址",
                "手机号",
                "签发机关",
                "有限起始日期",
                "有限结束日期",
                "错误信息");
        try {
            // 导出
            if (dataList.size()>0) {
                String s = ExcelUtils.downloadExcel(headList, dataList, "导入失败数据导出", response, cerPersonFileInDisk);
                HashMap<String,Object> res =new HashMap<>();
                res.put("errorFile", s);
                return JsonObj.success(res);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return JsonObj.error("错误数据导出失败");
//            logger.warn(e.toString());
        }
        return JsonObj.success("数据导入成功");
    }



    private CerPersonalInfo getCerPersonalInfo(CerPersonalData each) {
        CerPersonalInfo target = new CerPersonalInfo();
        target.setName(each.getName());
        target.setIdCard(each.getIdCard());
        target.setSex(each.getSex());
        target.setAddr(each.getAddr());
        target.setPhone(each.getPhone());
        target.setBirthday(each.getBirthday());
        target.setCityName(each.getCityName());
        target.setCountyName(each.getCountyName());
        target.setProvinceName(each.getProvinceName());
        target.setDistrictName(each.getDistrictName());
        target.setNationCode(each.getNationCode());
        target.setVillageName(each.getVillageName());
        target.setQfjg(each.getQfjg());
        target.setYxStartDate(each.getYxStartDate());
        target.setYxEndDate(each.getYxEndDate());
        return target;
    }
    private LinkedHashMap<String,Object> toLinkedHashMap(CerPersonalInfo each){
        LinkedHashMap<String, Object> target = new LinkedHashMap<String, Object>();
        target.put("provinceName",each.getProvinceName());
        target.put("cityName",each.getCityName());
        target.put("districtName",each.getDistrictName());
        target.put("countyName",each.getCountyName());
        target.put("villageName",each.getVillageName());
        target.put("name",each.getName());
        target.put("sex",each.getSex());
        target.put("nationCode",each.getNationCode());
        target.put("idCard",each.getIdCard());
        target.put("birthday",each.getBirthday());
        target.put("addr",each.getAddr());
        target.put("phone",each.getPhone());
        target.put("qfjg",each.getQfjg());
        target.put("yxStartDate",each.getYxStartDate());
        target.put("yxEndDate",each.getYxEndDate());
        target.put("errorMsg",each.getErrorMessage());
        return target;
    }


    private String generateCerDataInitFileSavePath( MultipartFile file, String userId) {
        // 生成新的文件名称
        String fileName =
                DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS") + "_" + userId + "_" + file
                        .getOriginalFilename()
                        .substring(0,
                                file
                                        .getOriginalFilename()
                                        .lastIndexOf('.')) + file
                        .getOriginalFilename()
                        .substring(file
                                .getOriginalFilename()
                                .lastIndexOf('.'));

        // 生成文件的存放路径
        // 日期目录
        String dirName = cerPersonFileInDisk + DateFormatUtils.format(new Date(), "yyyyMMdd");
        File dir = new File(dirName);
        if (!dir.exists()) {
            dir.mkdirs();
        }
        return dirName + "/" + fileName;
    }


    @PostMapping("queryAllExportData")
    @ApiOperation("查询待导出的所有数据")
    public JsonObj queryAllExportData(@RequestBody PageData pageData) {
        List<LinkedHashMap<String, Object>> list = personInfoService.queryAllExportDataBy(pageData);
        Map<String, Object> map = new HashedMap<>();
        map.put("data", list);
        return JsonObj.success(map);
    }

    /**
     * 人员信息删除
     */
    @GetMapping("/delPersonInfo")
    public JsonObj delPersonInfo(@RequestParam String id) {
        return personInfoService.delPersonInfo(id);
    }
}
